#include "StateManager.h"

StateManager * StateManager::m_pInstance = NULL;

StateManager::StateManager()
	: m_pPrevState(NULL), m_pCurrState(NULL), m_pNextState(NULL)
{
	LOGIDBG("Itit StateManager\n");
	MessageServer::Instance->Register(this, FW_CHANGE_STATE, CallBackInternalSwitch);
}

StateManager::~StateManager()
{
	LOGIDBG("Destroy StateManager\n");
	SAFE_DEL(m_pPrevState);
	SAFE_DEL(m_pCurrState);
	SAFE_DEL(m_pNextState);
}

StateManager * StateManager::GetInstance()
{
	if (!m_pInstance)
		m_pInstance = new StateManager();
	return m_pInstance;
}

void StateManager::DestroyInstance()
{
	SAFE_DEL(m_pInstance);
}

void StateManager::RegisterState(const char* szName, State * pState)
{
	if (!pState)
	{
		LOGE("Can't reg null state");
		return;
	}

	//Search in list, if State is existed, it wouldn't be added into list
	std::map<const char*, State*>::iterator temp = m_lstPrepState.find(szName);

	if (temp != m_lstPrepState.end())
	{
		LOGW("State %s has already existed\n", szName);
		return;
	}

	m_lstPrepState[szName] = pState;
}

void StateManager::Switch(const char * szName)
{
	std::map<const char*, State*>::iterator temp = m_lstPrepState.find(szName);
	if (temp == m_lstPrepState.end())
	{
		LOGW("State %s isn't exist.\n", szName);
		return;
	}
	m_pNextState = temp->second;
}

void StateManager::RemoveState(const char* szName)
{
	std::map<const char*, State*>::iterator temp = m_lstPrepState.find(szName);

	if (temp == m_lstPrepState.end())
	{
		LOGW("State %s isn't exist.\n", szName);
		return;
	}

	temp->second->Destroy();
	SAFE_DEL(temp->second);
	m_lstPrepState.clear();
}

void StateManager::InternalSwitch()
{
	if (m_pNextState)
	{
		if (m_pCurrState)
		{
			m_pPrevState = m_pCurrState;
			m_pCurrState->Destroy();
		}
		m_pCurrState = m_pNextState;
		m_pCurrState->Init();
		m_pNextState = NULL;
	}
}

void StateManager::ExternalSwitch()
{
	InternalSwitch();
}

State * StateManager::GetCurrentState()
{
	return m_pCurrState;
}